home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac: Not for Sale / Another.not.for.sale (Australia).iso / hold me in your arms / PGP 2.6 / rsaref Toolkit / source / desc.c < prev    next >
C/C++ Source or Header  |  1992-02-29  |  10KB  |  321 lines

  1. /* DESC.C - Data Encryption Standard routines for RSAREF
  2.  */
  3.  
  4. #include "global.h"
  5. #include "rsaref.h"
  6. #include "des.h"
  7.  
  8. /* Initial permutation IP.
  9.  */
  10. unsigned char IP[64] = {
  11.   58, 50, 42, 34, 26, 18, 10,  2, 60, 52, 44, 36, 28, 20, 12,  4,
  12.   62, 54, 46, 38, 30, 22, 14,  6, 64, 56, 48, 40, 32, 24, 16,  8,
  13.   57, 49, 41, 33, 25, 17,  9,  1, 59, 51, 43, 35, 27, 19, 11,  3,
  14.   61, 53, 45, 37, 29, 21, 13,  5, 63, 55, 47, 39, 31, 23, 15,  7
  15. };
  16.  
  17. /* Final permutation FP = IP^{-1}.
  18.  */
  19. unsigned char FP[64] = {
  20.   40,  8, 48, 16, 56, 24, 64, 32, 39,  7, 47, 15, 55, 23, 63, 31, 
  21.   38,  6, 46, 14, 54, 22, 62, 30, 37,  5, 45, 13, 53, 21, 61, 29, 
  22.   36,  4, 44, 12, 52, 20, 60, 28, 35,  3, 43, 11, 51, 19, 59, 27, 
  23.   34,  2, 42, 10, 50, 18, 58, 26, 33,  1, 41,  9, 49, 17, 57, 25
  24. };
  25.  
  26. /* Permuted-choice 1.
  27.  */
  28. unsigned char PC1[] = {
  29.   57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
  30.   10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
  31.   63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
  32.   14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4
  33. };
  34.  
  35. /* Left shifts for the key schedule.
  36.  */
  37. unsigned char LS[16] = {
  38.   1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
  39. };
  40.  
  41. /* Permuted-choice 2.
  42.  */
  43. unsigned char PC2[] = {
  44.   14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
  45.   23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
  46.   41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 
  47.   44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
  48. };
  49.  
  50. /* Bit-selection table E.
  51.  */
  52. unsigned char E[] = {
  53.   32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,
  54.    8,  9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
  55.   16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
  56.   24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32,  1
  57. };
  58.  
  59. /* Selection functions (S-boxes). [[These are 0-origin indexed.]]
  60.  */
  61. unsigned char S[8][64] = {
  62.   14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  63.    0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  64.    4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  65.   15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
  66.  
  67.   15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  68.    3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  69.    0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  70.   13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
  71.  
  72.   10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  73.   13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  74.   13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  75.    1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
  76.  
  77.    7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  78.   13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  79.   10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  80.    3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
  81.  
  82.    2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  83.   14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  84.    4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  85.   11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
  86.  
  87.   12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  88.   10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  89.    9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  90.    4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
  91.  
  92.    4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  93.   13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  94.    1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  95.    6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
  96.  
  97.   13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  98.    1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  99.    7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  100.    2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
  101. };
  102.  
  103. /* Permutation P.
  104.  */
  105. unsigned char P[32] = {
  106.   16,  7, 20, 21, 29, 12, 28, 17,  1, 15, 23, 26,  5, 18, 31, 10,
  107.    2,  8, 24, 14, 32, 27,  3,  9, 19, 13, 30,  6, 22, 11,  4, 25
  108. };
  109.  
  110. static void Unpack PROTO_LIST
  111.   ((unsigned char *, unsigned char *, unsigned int));
  112. static void Pack PROTO_LIST
  113.   ((unsigned char *, unsigned char *, unsigned int));
  114.  
  115. /* DES-CBC initialization. Begins a DES-CBC operation, writing a new
  116.    context.
  117.  */
  118. void DES_CBCInit (context, key, iv, encrypt)
  119. DES_CBC_CTX *context;                                    /* DES-CBC context */
  120. unsigned char key[8];                                            /* DES key */
  121. unsigned char iv[8];                             /* DES initializing vector */
  122. int encrypt;                     /* encrypt flag (1 = encrypt, 0 = decrypt) */
  123. {
  124.   unsigned char CD[56], keyBit[64], t;
  125.   unsigned int i, j;
  126.  
  127.   /* Copy encrypt flag to context.
  128.    */
  129.   context->encrypt = encrypt;
  130.  
  131.   /* Unpack initializing vector into context.
  132.    */
  133.   Unpack (context->ivBit, iv, 8);
  134.  
  135.   /* Unpack key and generate C and D by permuting the key according to PC1.
  136.    */
  137.   Unpack (keyBit, key, 8);
  138.   for (i = 0; i < 56; i++)
  139.     CD[i] = keyBit[PC1[i]-1];
  140.   
  141.   /* Generate subkeys Ki by rotating C and D according to schedule and
  142.      permuting C and D according to PC2.
  143.    */
  144.   for (i = 0; i < 16; i++) {
  145.     for (j = 0; j < LS[i]; j++) {
  146.       t = CD[0];
  147.       R_memcpy ((POINTER)CD, (POINTER)&CD[1], 27);
  148.       CD[27] = t;
  149.       t = CD[28];
  150.       R_memcpy ((POINTER)&CD[28], (POINTER)&CD[29], 27);
  151.       CD[55] = t;
  152.     }
  153.     
  154.     for (j = 0; j < 48; j++)
  155.       context->subkeyBit[i][j] = CD[PC2[j]-1];
  156.   }
  157.  
  158.   /* Zeroize sensitive information.
  159.    */
  160.   R_memset ((POINTER)CD, 0, sizeof (CD));
  161.   R_memset ((POINTER)keyBit, 0, sizeof (keyBit));
  162. }
  163.  
  164. /* DES-CBC block update operation. Continues a DES-CBC encryption
  165.    operation, processing eight-byte message blocks, and updating
  166.    the context.
  167.  */
  168. int DES_CBCUpdate (context, output, input, len)
  169. DES_CBC_CTX *context;                                    /* DES-CBC context */
  170. unsigned char *output;                                      /* output block */
  171. unsigned char *input;                                        /* input block */
  172. unsigned int len;                      /* length of input and output blocks */
  173. {
  174.   unsigned char inputBit[64], LR[64], newL[32], outputBit[64], sInput[48],
  175.     sOutput[32], t;
  176.   unsigned int i, j, k;
  177.   
  178.   if (len % 8)
  179.     return (RE_LEN);
  180.   
  181.   for (i = 0; i < len/8; i++) {
  182.  
  183.     /* Unpack input block and set LR = IP(input ^ iv) (encrypt) or
  184.        LR = IP(input) (decrypt).
  185.      */
  186.     Unpack (inputBit, &input[8*i], 8);
  187.   
  188.     if (context->encrypt)
  189.       for (j = 0; j < 64; j++)
  190.         LR[j] = inputBit[IP[j]-1] ^ context->ivBit[IP[j]-1];
  191.     else
  192.       for (j = 0; j < 64; j++)
  193.         LR[j] = inputBit[IP[j]-1];
  194.   
  195.     /* 16 rounds.
  196.      */
  197.     for (j = 0; j < 16; j++) {
  198.     
  199.       /* Save R, which will be the new L.
  200.        */
  201.       R_memcpy ((POINTER)newL, &LR[32], 32);
  202.  
  203.       /* Compute sInput = E(R) ^ Kj (encrypt) or sInput = E(R) ^ K{15-j}
  204.          (decrypt).
  205.        */
  206.       if (context->encrypt)
  207.         for (k = 0; k < 48; k++)
  208.           sInput[k] = LR[E[k]+31] ^ context->subkeyBit[j][k];
  209.       else
  210.         for (k = 0; k < 48; k++)
  211.           sInput[k] = LR[E[k]+31] ^ context->subkeyBit[15-j][k];
  212.     
  213.       /* Apply eight S boxes. Index into S box k is formed from these
  214.          bits of sInput:
  215.  
  216.                   6*k 6*k+5 6*k+1 6*k+2 6*k+3 6*k+4
  217.  
  218.          Value of S box k becomes these bits of sOutput:
  219.          
  220.                         4*k 4*k+1 4*k+2 4*k+3
  221.        */
  222.       for (k = 0; k < 8; k++) {
  223.         t = S[k][(sInput[6*k] << 5) | (sInput[6*k + 5] << 4) |
  224.                  (sInput[6*k + 1] << 3) | (sInput[6*k + 2] << 2) |
  225.                  (sInput[6*k + 3] << 1) | (sInput[6*k + 4] << 0)];
  226.  
  227.         sOutput[4*k] = (unsigned char)((t >> 3) & 1);
  228.         sOutput[4*k + 1] = (unsigned char)((t >> 2) & 1);
  229.         sOutput[4*k + 2] = (unsigned char)((t >> 1) & 1);
  230.         sOutput[4*k + 3] = (unsigned char)(t & 1);
  231.       }
  232.  
  233.       /* Compute new R = L ^ P(sOutput).
  234.        */
  235.       for (k = 0; k < 32; k++)
  236.         LR[k+32] = LR[k] ^ sOutput[P[k]-1];
  237.     
  238.       /* Restore new L.
  239.        */
  240.       R_memcpy ((POINTER)LR, (POINTER)newL, 32);
  241.     }
  242.  
  243.     /* Exchange L and R.
  244.      */
  245.     R_memcpy ((POINTER)newL, (POINTER)&LR[32], 32);
  246.     R_memcpy ((POINTER)&LR[32], (POINTER)LR, 32);
  247.     R_memcpy ((POINTER)LR, (POINTER)newL, 32);
  248.  
  249.     /* Set output = FP(LR) (encrypt) or FP(LR) ^ iv (decrypt), and pack
  250.        output block.
  251.      */
  252.     if (context->encrypt)
  253.       for (j = 0; j < 64; j++)
  254.         outputBit[j] = LR[FP[j]-1];
  255.     else
  256.       for (j = 0; j < 64; j++)
  257.         outputBit[j] = LR[FP[j]-1] ^ context->ivBit[j];
  258.  
  259.     Pack (&output[8*i], outputBit, 8);
  260.   
  261.     /* Set iv = output (encrypt) or iv = input (decrypt).
  262.      */
  263.     if (context->encrypt)
  264.       R_memcpy ((POINTER)context->ivBit, (POINTER)outputBit, 64);
  265.     else
  266.       R_memcpy ((POINTER)context->ivBit, (POINTER)inputBit, 64);
  267.   }
  268.   
  269.   /* Zeroize sensitive information.
  270.    */
  271.   R_memset ((POINTER)inputBit, 0, sizeof (inputBit));
  272.   R_memset ((POINTER)LR, 0, sizeof (LR));
  273.   R_memset ((POINTER)newL, 0, sizeof (newL));
  274.   R_memset ((POINTER)outputBit, 0, sizeof (outputBit));
  275.   R_memset ((POINTER)sInput, 0, sizeof (sInput));
  276.   R_memset ((POINTER)sOutput, 0, sizeof (sOutput));
  277.   t = 0;
  278.   
  279.   return (0);
  280. }
  281.  
  282. /* DES-CBC finalization operation. Ends a DES-CBC encryption operation,
  283.    zeroizing the context.
  284.  */
  285. void DES_CBCFinal (context)
  286. DES_CBC_CTX *context;
  287. {
  288.   R_memset ((POINTER)context, 0, sizeof (*context));
  289. }
  290.  
  291. static void Unpack (bit, block, blockLen)
  292. unsigned char *bit;                                            /* bit array */
  293. unsigned char *block;                                         /* byte array */
  294. unsigned int blockLen;                              /* length of byte array */
  295. {
  296.   unsigned int i, j;
  297.   unsigned char t;
  298.  
  299.   for (i = 0; i < blockLen; i++) {
  300.     t = block[i];
  301.     for (j = 0; j < 8; j++)
  302.       bit[8*i + j] = (unsigned char)((t >> (7-j)) & 1);
  303.   }
  304. }
  305.  
  306. static void Pack (block, bit, blockLen)
  307. unsigned char *block;                                         /* byte array */
  308. unsigned char *bit;                                            /* bit array */
  309. unsigned int blockLen;                              /* length of byte array */
  310. {
  311.   unsigned int i, j;
  312.   unsigned char t;
  313.  
  314.   for (i = 0; i < blockLen; i++) {
  315.     t = 0;
  316.     for (j = 0; j < 8; j++)
  317.       t |= bit[8*i +j] << (7-j);
  318.     block[i] = t;
  319.   }
  320. }
  321.